

#include "rtc.h"

bool RTC_irq_Flag = false;

u32 real_tim_acc_sec;

time_t time_acc_sec; 

void RTC_Init(void)
{

//(when the first time the program is executed),以后每次上电并不执行。  
/* Backup data register value is not correct or not yet programmed */
  if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  {  
    RTC_Configuration();

    printf("\r\n RTC configured OK!");
    
  /* Change the current time */
   //RTC_SetCounter(get_daytime());// 如果不起作用,m...
    RTC_SetCounter(28800);
    
    RTC_WaitForLastTask();
     
    BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  }
  else /* Backup data register value is correct or has been programmed */
  {
    /* Check if the Power On Reset flag is set */
    if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    {
      printf("\r\n\n Power On occurred....");
    }
    /* Check if the Pin Reset flag is set */
    else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    {
      printf("\r\n\n External Reset occurred....");
    }
  
    printf("\r\n No need to configure RTC....");
    
    RTC_WaitForSynchro();/* Wait for RTC registers synchronization */
    RTC_WaitForLastTask();
	  
    RTC_ITConfig(RTC_IT_SEC, ENABLE);/* Enable the RTC Second */
    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();
	
  }
  
  RCC_ClearFlag();  /* Clear reset flags */

}

/*******************************************************************************
* Function Name  : RTC_Configuration
* Description    : Configures the RTC.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_Configuration(void)
{
  
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); 
  
  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);
  
  /* Reset Backup Domain */
  BKP_DeInit();

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  
  /* Wait till LSE is ready */
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  
  /* Enable the RTC Second */
  RTC_ITConfig(RTC_IT_SEC, ENABLE);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  
  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
  
  /* Wait until last write operation on RTC registers has finished */
  
  RTC_WaitForLastTask();
  /* Modified History:
    1.http://wenku.baidu.com/link?url=bR92Q4B_4VKE9uviAyCm0Bdy7o-vDYwXjsheQQIUNIe1j9xRAgpnjf3z8bpFcBJq8LX25GYTLVIwMo1t9OW-lRMMG7k5qhLp7ljWKLmKrty
    2. 2016.10.07 ppm : 34-32-(84s) 
  */
  /*根据实际环境测量来确定校正值,这里以每月84秒来校正*/
  BKP_SetRTCCalibrationValue(34); // slow down 84s per month
  
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  
  
}



/*******************************************************************************
* Function Name  : RTC_IRQHandler
* Description    : This function handles RTC global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_IRQHandler(void)
{
  if(RTC_GetITStatus(RTC_IT_SEC) != RESET) // 秒中断
  {
    /* Clear the RTC Second interrupt */
    RTC_ClearITPendingBit(RTC_IT_SEC);
    RTC_irq_Flag = !RTC_irq_Flag;
    
    LED_Toggle(LED0); /* Toggle led connected pin each 1s */
	
    /* Enable time update */
     real_tim_acc_sec= RTC_GetCounter();
    
     // printf(ctime(&real_tim_acc_sec)); //[Wed Aug 12 19:37:03 2015] ,for debug: dec to str 

  }

	if(RTC_GetITStatus(RTC_IT_ALR)!=RESET)//闹钟中断 
	{ 
		RTC_ClearITPendingBit(RTC_IT_ALR);
		RTC_WaitForLastTask(); 
		//AlmIndex = 1; 
	} 
  
}



/*******************************************************************************
* Function Name  : get_daytime
* Description    : 把系统编译的字符串时间日期转换成Unix时间戳(日历时间)
* Input          : 
* Output         : time_acc_sec
*******************************************************************************/
time_t get_daytime(void)
{

 // char compiled_time[8] = __TIME__;     //[23:20:59]
 // char compiled_date[11]  =  __DATE__ ; // 格式：[Nov 12 2015] 

  
  char compiled_time[8] = "10:38:59";     //[23:20:59]
  char compiled_date[11]  = "Jul 26 2015"; // 格式：[Nov 12 2015] 
  
  
  char month_str[3]; //[0,11] 
  char year_str[4];
  
  strncpy(month_str, compiled_date, 3); // copy the compiled_date first 3 char to month_str 
   
   if (!strcmp("Jan",month_str))     //当s1=s2时，返回值=0
   {
	   rtc.tm_mon=0;
   }
   else if(!strcmp("Feb",month_str))  
   {
	   rtc.tm_mon=1;
   }
   else if(!strcmp("Mar",month_str))
  	{
	   rtc.tm_mon=2;
   }
   else if(!strcmp("Apr",month_str))
   {
	   rtc.tm_mon=3;
   }	 	
    else if(!strcmp("May",month_str))
    {
    rtc.tm_mon=4;
    }  	 	
    else if(!strcmp("Jun",month_str)) 
    {
            rtc.tm_mon=5;
    }
			 	
   else if(!strcmp("Jul",month_str))  
   {
	   rtc.tm_mon=6;
   }
   else if(!strcmp("Aug",month_str))
  	{
	   rtc.tm_mon=7;
   }
   else if(!strcmp("Sep",month_str))
   {
	   rtc.tm_mon=8;
   }	 	
	else if(!strcmp("Oct",month_str))
	{
	  rtc.tm_mon=9;
	}	 	
	else if(!strcmp("Nov",month_str)) 
	{
            rtc.tm_mon=10;
	}
	else  if(!strcmp("Dec",month_str)) 
        {
            rtc.tm_mon=11;
        }
	else return 0;	
 
 memcpy(year_str,compiled_date+7,4); //compiled_date中第8个开始的连续4个复制到year_str

 rtc.tm_year=atoi(year_str)-1900;  //str to zhengshu,  resault: 115 

//rtc.tm_mday= atoi(compiled_date); //月中的日期,// atoi: str to zhengshu
rtc.tm_mday= (compiled_date[4]-0x30)*10+compiled_date[5]-0x30; //[1,31] 

rtc.tm_hour=(compiled_time[0]-0x30)*10+(compiled_time[1]-0x30); 
rtc.tm_min=(compiled_time[3]-0x30)*10+(compiled_time[4]-0x30); 
rtc.tm_sec=(compiled_time[6]-0x30)*10+(compiled_time[7]-0x30); 

rtc.tm_isdst=0; 

//printf("%d,%d,%d,%d,d%,d%\n",rtc.tm_year,rtc.tm_mon,rtc.tm_mday,rtc.tm_hour,rtc.tm_min,rtc.tm_sec);

time_acc_sec=mktime(&rtc); //1970年1月1日以来持续时间的秒数，即Unix时间! 实验结果：

printf(ctime(&time_acc_sec)); //[Wed Aug 12 19:37:03 2015] ,for debug: dec to str 
    
  return time_acc_sec;   
}


